import { Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { SysVisitLog } from '../../entities/sys-visit-log.entity';
import * as useragent from 'useragent';
import { InjectRedis } from '@nestjs-modules/ioredis';
import Redis from 'ioredis';

@Injectable()
export class VisitLogMiddleware implements NestMiddleware {
  constructor(
    @InjectRepository(SysVisitLog)
    private visitLogRepository: Repository<SysVisitLog>,
    @InjectRedis() private readonly redis: Redis,
  ) {}

  async use(req: Request, res: Response, next: NextFunction) {
    // 排除不需要记录的路径，例如静态资源、健康检查等
    const excludePaths = ['/api-docs', '/favicon.ico', '/health', '/static'];
    if (excludePaths.some(path => req.path.startsWith(path))) {
      return next();
    }

    // 记录请求开始时间
    const startTime = Date.now();

    // 当请求结束时记录日志
    res.on('finish', async () => {
      try {
        // 计算请求持续时间
        const duration = Math.floor((Date.now() - startTime) / 1000);

        // 解析User-Agent
        const agent = useragent.parse(req.headers['user-agent']);
        
        // 获取IP地址
        const ip = this.getClientIp(req);

        // 从请求中提取用户ID (如果用户已登录)
        const userId = (req as any).user?.id;

        // 创建访问日志
        const visitLog = this.visitLogRepository.create({
          ip,
          userId,
          url: req.originalUrl || req.url,
          userAgent: req.headers['user-agent'],
          referer: req.headers['referer'],
          browser: agent.family,
          os: agent.os.toString(),
          device: this.getDeviceType(req.headers['user-agent']),
          duration,
          visitTime: new Date(),
        });

        // 保存到数据库
        await this.visitLogRepository.save(visitLog);

        // 更新Redis中的实时统计数据
        await this.updateRedisStats(ip);

        // console.log('Visit logged:', visitLog);
      } catch (error) {
        console.error('Failed to log visit:', error);
      }
    });

    next();
  }

  private getClientIp(req: Request): string {
    return req.headers['x-forwarded-for'] as string || 
           req.socket.remoteAddress || 
           '';
  }

  private getDeviceType(userAgent: string): string {
    return /mobile|android|iphone|ipad|phone/i.test(userAgent) 
      ? 'Mobile' 
      : 'PC';
  }

  private async updateRedisStats(ip: string) {
    const today = new Date().toISOString().split('T')[0]; // 格式: YYYY-MM-DD
    
    // 更新当日PV（浏览量）
    await this.redis.hincrby('stats:daily', `pv:${today}`, 1);
    
    // 更新当日IP（访客数）- 使用集合确保每个IP只计数一次
    await this.redis.sadd(`stats:ip:${today}`, ip);
    
    // 更新总PV
    await this.redis.hincrby('stats:total', 'pv', 1);
    
    // 更新总UV（基于IP）
    await this.redis.sadd('stats:total:ip', ip);
  }
}